# coding:utf-8
# writingtime: 2022-8-13

import random as rm
import matplotlib.pyplot as plt
from math import log10
from IVq_ROF_20220811 import GetTestData
from Utilities.Plot.SimplePlot import SimpleClass
from scoreFunction import f0


class Analyze(GetTestData):
    def __init__(self, scorefunc, q, deviationsize=None):
        """

        :param scorefunc: 得分函数的函数表达式
        :param  q: 区间值广义正交模糊集的参数
        :param deviationsize: 精度
        """
        super(Analyze, self).__init__(deviationsize)
        self.numb_round = int(log10(1 / self.deviation))
        self.func = scorefunc
        self.q = q
        self.imgShow = True
        self.imgSaving = False
        # 取值相等的线最多画5条
        self.maxnumb = 5

    def assist1(self,dict_data):
        """
        function: 筛选辅助函数
        :param dict_data: 字典元素
        :return:
        """
        return [i[0] for i in list(filter(lambda x: len(x[1]) > 0, list(dict_data.items())))]

    def method1(self, data=None, dataname='Title'):
        """

        :param data:列表中的每个元素只有一个模糊数
        :param dataname: 标题
        :return:
        """
        if data is None:
            data = self.case2()
        # 所有的得分
        score = []
        # 统计保留self.numb_round位小数时，得分相等的情况
        dict_temp = {}
        for i in data:
            temp = round(self.func(i[0], self.q), self.numb_round)
            score.append(temp)
            dict_temp[temp] = dict_temp.get(temp, []) + i
        # 筛选出取值相等的结果哦
        # same_score = [i[0] for i in list(filter(lambda x: len(x[1]) > 0, list(dict_temp.items())))]
        same_score = self.assist1(dict_temp)
        del dict_temp
        length = len(same_score)
        same_lis = set([])
        # rm.seed(100)
        if length > self.maxnumb:
            while self.maxnumb:
                same_lis.add(same_score[rm.randint(0, length - 1)])
                self.maxnumb -= 1
            same_lis = list(same_lis)
        else:
            same_lis = same_score
        # 绘制特定的图像
        fig, ax = plt.subplots(figsize=(12.5, 7.2))
        plt.title(dataname)
        plt.xlabel('N')
        plt.ylabel('Score')
        ax.plot([i + 1 for i in range(len(score))], score, label='Score Function', linewidth=1, ms=5)
        # 绘制横向的标记线
        ax.hlines(same_lis, [len(score)], [1 for _ in range(len(same_lis))], color='red', linewidth=1,
                  label='Same Value')
        # 给横向的标记线加上数值,标注的数值大小可以自己调参数size
        # print(same_lis)
        for i in same_lis:
            plt.annotate(i, xy=(len(score), i), xytext=(len(score), i), size=7)
        plt.legend(bbox_to_anchor=(1.1, 1.155))  # 显示标签
        plt.grid(b=True, axis='y')
        if self.imgShow:
            plt.show()
        """后续添加"""
        if self.imgSaving:
            pass
        plt.close()
        return score

    def method2(self, data, dataname='Title'):
        """

        :param data: 列表中的元素只有两个模糊数
        :param dataname: 标题名
        :return:
        """
        length = len(data)
        li1 = []
        li2 = []
        for i in data:
            score1 = self.func(i[0], self.q)
            li1.append(score1)
            score2 = self.func(i[1], self.q)
            li2.append(score2)
        SimpleClass().qSensitivity([li1, li2], [i + 1 for i in range(length)], title=dataname,
                                   label_list=["Basis Point","Score Function"],marksize=2)

    def analyze(self, casefun):
        """

        :param funcase: 案例的函数表达式
        :return:
        """
        data = casefun()
        if len(data[0]) == 1:
            self.method1(data, casefun.__name__)
        if len(data[0]) == 2:
            self.method2(data, casefun.__name__)

    @staticmethod
    def test(scorefunc=None, q=None, deviationsize=None):
        """

        :param scorefunc:
        :param q:
        :param deviationsize:
        :return:
        """
        from scoreFunction import f1

        q = 3
        deviationsize = 0.0001
        data=GetTestData(deviationsize)
        Analyze(f1, q, deviationsize).analyze(data.case2)
        Analyze(f1, q, deviationsize).analyze(data.case3)
        Analyze(f1, q, deviationsize).analyze(data.case4)
        # ex.analyze(ex.case1)
        # ex.analyze(ex.case2)
        # ex.analyze(ex.case3)
        # ex.analyze(ex.case4)
        """****************"""
        # ex.analyze(ex.case5)
        # ex.analyze(ex.case6)
        # ex.analyze(ex.case7)
        # ex.analyze(ex.case8)
        # ex.analyze(ex.case9)
        # ex.analyze(ex.case10)
        # ex.analyze(ex.case11)
        # ex.analyze(ex.case12)


if __name__ == "__main__":
    Analyze.test()
    # e = Analyze(f0, 3, 0.01)
    # e.method1()
    print()
